#include "scriptServer.h"
#include "sgeString.h"

using namespace sge;

#include <sstream>

ScriptServer::ScriptServer() {
    printf("init scriptServer\n");

    Py_Initialize();
    
    using namespace boost::python;
    context = new object(handle<>(borrowed(PyImport_AddModule("__main__"))));
    
    importModule("sys").attr("path").attr("insert")(0,"");
}

ScriptServer::~ScriptServer() {
    functions.clear();
    delete context;

    Py_Finalize();
    
    printf("destroy scriptServer\n");
}

PythonObject ScriptServer::importModule(const String& filename) {
    int dotPos = filename.rfind(".");
    String name = filename.substr(0,dotPos);
    int pathPos = name.rfind("/");
    if (pathPos == String::npos) {
        return context->attr("__builtins__").attr("__import__")(name);
    } else {
        String path = name.substr(0,pathPos),
            newName = name.substr(pathPos+1);
        importModule("sys").attr("path").attr("insert")(0,path);
        return context->attr("__builtins__").attr("__import__")(newName);
    }
}

String ScriptServer::getType(PythonObject obj) {
    return boost::python::extract<String>(obj.attr("__class__").attr("__name__"));
}

int ScriptServer::getLength(PythonObject obj) {
    return boost::python::extract<int>(obj.attr("__len__")());
}

String ScriptServer::toString(PythonObject obj) {
    return boost::python::extract<String>(context->attr("__builtins__").attr("repr")(obj));
}

String ScriptServer::dir(PythonObject obj) {
    return toString(context->attr("__builtins__").attr("dir")(obj));
}

bool ScriptServer::hasFunction(const String& name) {
    return functions.find(name) != functions.end();
}

PythonObject ScriptServer::getFunction(const String& name) {
    if (hasFunction(name)) {
        return functions[name];
    } else
        return PythonObject();
}

bool ScriptServer::loadFunctions(const String& filename) {
    PythonObject module = importModule(filename),
        items = module.attr("__dict__").attr("items")();
    int len = getLength(items), i;
    String type, name;
    for (i = 0; i < len; ++i) {
        type = getType(items[i][1]);
        if (type == "function") {
            name = boost::python::extract<String>(items[i][0]);
            functions[name] = items[i][1];
            printf("loaded script action %s\n",name.c_str());
        }
    }
}

PythonObject ScriptServer::getContext() {
    return *context;
}
